Qt.include("Utility.js")
Qt.include("Constants.js")

var units = new Array(maxIndex);
var selectors = new Array(maxIndex);
var bombs = new Array(maxIndex);
var unitComponent, selectorComponent;
var obstacles = new Array(maxIndex);
var currentTurn = HUMAN_TEAM
var kingDead = 3 // 3 - game is running, 2 - 2nd team won, 1 - 1st team won, 0 - draw
var map = new Array()
var tiles = new Array()

//Simplified game initialization
function initGame(){
    kingDead = 3 // init game with both kings
    //Cleanup game board
    for(var i=0;i<maxIndex;i++){
        if (units[i] != null) {
            units[i].destroy();
            units[i] = null;
        }
    }

    if (unitComponent == null) unitComponent = Qt.createComponent("units/Pawn.qml");
    if (unitComponent.status == Component.Error)  console.log("Error loading component:", unitComponent.errorString());
    //Following two loops are placeholders - used to place teams on top and bottom rows
    for (var i = 1; i < 3; i++){
        var ind = index(i,0);
        units[ind] = unitComponent.createObject(field);
        with (units[ind]){
            x = i * cellSize;
            y = 0
            index = ind;
            team = 1
            z = 5
        }
    }
    var kingComponent = Qt.createComponent("units/King.qml")
    var ind1 = index(3,0);
    var ind2 = index(3,maxRow-1);
    units[ind1] = kingComponent.createObject(field)
    units[ind1].x = 3 * cellSize
    units[ind1].y = 0
    units[ind1].index = ind1
    units[ind1].team = 1
    units[ind1].z = 5
    units[ind2] = kingComponent.createObject(field)
    units[ind2].x = 3 * cellSize
    units[ind2].y = (maxRow-1)*cellSize
    units[ind2].index = ind2
    units[ind2].team = 0
    units[ind2].z = 5

    for (var i = 4; i < 6; i++){
        var ind = index(i,0);
        units[ind] = unitComponent.createObject(field);
        with (units[ind]){
            x = i * cellSize;
            y = 0
            index = ind;
            team = 1
            z = 5
        }
    }
    for (var i = 1; i < 3; i++){
        var ind = index(i,maxRow-1);
        units[ind] = unitComponent.createObject(field);
        with (units[ind]){
            x = i * cellSize;
            y = (maxRow-1) * cellSize
            index = ind;
            team = 0
            z = 5
        }
    }
    for (var i = 4; i < 6; i++){
        var ind = index(i,maxRow-1);
        units[ind] = unitComponent.createObject(field);
        with (units[ind]){
            x = i * cellSize;
            y = (maxRow-1) * cellSize
            index = ind;
            team = 0
            z = 5
        }
    }

    loadField()
}

function loadField(fieldName){
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "maps/field1.json");
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            var json = JSON.parse(xhr.responseText);

            var baseTile = Qt.createQmlObject('import QtQuick 2.0; Image{anchors.fill:parent;fillMode: Image.Tile;z:0;source:"gfx/basetile-' +json.basetile+ '.png"}',field,"FieldBaseImage")
            baseTile.z = 0

            tiles = json.tiles
            for (var i=0;i<tiles.length;i++){
                var component = Qt.createComponent("Tile.qml")
                var tmp_tile = component.createObject(field)
                tmp_tile.x = tiles[i].x * cellSize
                tmp_tile.y = tiles[i].y * cellSize
                tmp_tile.index = tiles[i].index
                tmp_tile.source = "gfx/" + json.tileMap
            }

            map = json.obstacles
            for (var i=0;i<map.length;i++){
                var component = Qt.createComponent("obstacles/" +map[i].type+ ".qml")
                obstacles[index(map[i].x,map[i].y)] = component.createObject(field)
                with(obstacles[index(map[i].x,map[i].y)]){
                    x = map[i].x*cellSize
                    y = map[i].y*cellSize
                    z = 10
                }
            }
        }
    }
    xhr.send();
}

function handleClick(xPos, yPos){
    var cellX = Math.floor(xPos / cellSize);
    var cellY = Math.floor(yPos / cellSize);
    var clickIndex = index(cellX, cellY);

    //First, check if we have clicked the selector
    // and if so, make selector owner act accordingly (e.g. move)
    if (selectors[clickIndex] != null){
        switch(selectors[clickIndex].type){
        case "move":
            units[selectors[clickIndex].ownerIndex].moveTo(cellX, cellY)
            units[clickIndex] = units[selectors[clickIndex].ownerIndex]
            units[clickIndex].index = clickIndex
            units[clickIndex].moved = true
            units[selectors[clickIndex].ownerIndex] = null
            clearSelectors()
            return;
        case "throw":
            var bombComponent = Qt.createComponent("Bomb.qml")
            bombs[clickIndex] = bombComponent.createObject(field)
            bombs[clickIndex].x = cellX * cellSize
            bombs[clickIndex].y = cellY * cellSize
            bombs[clickIndex].index = clickIndex
            units[selectors[clickIndex].ownerIndex].thrown = true
            clearSelectors()
            return
        case "special":
            units[selectors[clickIndex].ownerIndex].specialTo(cellX, cellY)
            clearSelectors()
            return
        }
    }

    //Check if we clicked some unit and if so - show unit's context menu
    if (units[clickIndex] != null &&
            units[clickIndex].team == currentTurn) {
        clearSelectors()
        if (((cellX*cellSize) + (cellSize / 2) + contextMenu.width) > field.width){
            contextMenu.x = (cellX * cellSize) + (cellSize / 2) - contextMenu.width
        } else {
            contextMenu.x = (cellX * cellSize) + (cellSize / 2);
        }
        if (((cellY*cellSize) + (cellSize / 2) + contextMenu.height) > field.height){
            contextMenu.y = (cellY * cellSize) + (cellSize / 2) - contextMenu.height
        } else {
            contextMenu.y = (cellY * cellSize) + (cellSize / 2);
        }
        contextMenu.ownerIndex = clickIndex;
        contextMenu.visible = true;
    }
}

/**
  This function clears selectors array and deletes selectors objects from map
  */
function clearSelectors() {
    for (var i=0; i<maxIndex; i++){
        if (selectors[i] != null) {
            selectors[i].destroy();
            selectors[i] = null;
        }
    }
}

/**
  This function is used for re-generating selectors and drawing them on the board
  @param {integer} ownerIndex - index of the units array that holds unit, which all
  generated selectors will belong to
  @param {string} type - type of selector ("move", "throw" or "special")
  */
function drawSelectors(ownerIndex, type){
    clearSelectors();
    var selectorsIndices = new Array();
    selectorsIndices = units[ownerIndex].getSelectorIndices(type, units, obstacles, bombs)
    if (selectorComponent == null) selectorComponent = Qt.createComponent("Selector.qml");
    for (var i=0; i<selectorsIndices.length; i++){
        selectors[selectorsIndices[i]] = selectorComponent.createObject(field)
        selectors[selectorsIndices[i]].x = xFromIndex(selectorsIndices[i]) * cellSize
        selectors[selectorsIndices[i]].y = yFromIndex(selectorsIndices[i]) * cellSize
        selectors[selectorsIndices[i]].type = type
        selectors[selectorsIndices[i]].ownerIndex = ownerIndex
    }
}

/**
  This function ticks down timers for all bombs in a cycle
  */
function tickAll(){
    for (var i=0; i<maxIndex; i++) {
        if (bombs[i] != null){
            tick(bombs[i])
        }
    }
}

/**
  This function is used to tick down the bomb timer
  */
function tick(bomb){
    if ((bomb.timer - 1) <= 0) {
        detonate(bomb)
    }
    bomb.timer = bomb.timer - 1
}

/**
  This function does the bomb detonation and calls explosion spread procedure
  */
function detonate(bomb){
    var explInd = new Array()
    explInd = bomb.getExplosionIndices(units, obstacles, bombs)
    bombs[bomb.index] = null
    bomb.destroy()
    explode(explInd)
}

/**
  Explosion generating procedure. It draws explosions, kills units, destructs obstacles
  and detonates other bombs
  */
function explode(explosionIndices){
    var explosionComponent = Qt.createComponent("Explosion.qml")
    for (var i=0; i<explosionIndices.length; i++){
        var expl = explosionComponent.createObject(fieldCanvas)
        expl.x = xFromIndex(explosionIndices[i])*cellSize
        expl.y = yFromIndex(explosionIndices[i])*cellSize
        if(bombs[explosionIndices[i]] != null){
            detonate(bombs[explosionIndices[i]])
        } else if (units[explosionIndices[i]] != null){
            if (units[explosionIndices[i]].king) {
                kingDead = kingDead - (units[explosionIndices[i]].team+1)
            }
            units[explosionIndices[i]].destroy()
            units[explosionIndices[i]] = null
        } else if (obstacles[explosionIndices[i]] != null){
            if (obstacles[explosionIndices[i]].durability <= 1){
                obstacles[explosionIndices[i]].destroy()
                obstacles[explosionIndices[i]] = null
            } else {
                obstacles[explosionIndices[i]].durability = obstacles[explosionIndices[i]].durability - 1
            }
        }
    }
}

/**
  This function checks whether some team has won the round, clears selectors from field
  */
function nextTurn(){

    currentTurn = (currentTurn == HUMAN_TEAM) ? AI_TEAM : HUMAN_TEAM
    tickAll()
    clearSelectors()
    for (var i=0;i<maxIndex;i++){
        if(units[i] != null){
            units[i].moved=false
            units[i].thrown=false
            units[i].speced=false
        }
    }

    if (kingDead != 3) {
        gameover(kingDead)
    }

    nextTurnScreen.text = (currentTurn == HUMAN_TEAM ? "Player" : "CPU") + " turn!"
    nextTurnScreen.visible = true
}

function gameover(winTeam){
    switch(winTeam){
    case 2:
        winScreen.text = "CPU wins!"
        break
    case 1:
        winScreen.text = "Player wins!"
        break
    case 0:
        winScreen.text = "Draw!"
        break
    }
    winScreen.visible = true
}
